import _thread
import urequests
import ubinascii
from machine import I2S, Pin
import ujson
from setcfg import DAT
ASR_SERVER_URL = DAT["tts"]["url"]
# 初始化引脚定义
"""
    GPIO27 -- DIN
    GPIO26 --- BCLK
    GPIO2 -- LRC
    GND -- GND
    5V或3.3V -- VCC
"""
CHUNK = 1024
try:
    # 修改音频设备初始化
    i2s = I2S(
        1,
        sck=Pin(DAT["tts"]["sck"]), #BCLK
        ws=Pin(DAT["tts"]["ws"]),   #LRC
        sd=Pin(DAT["tts"]["sd"]),  #DIN
        mode=I2S.TX,
        bits=16,
        format=I2S.MONO,
        rate=24000,
        ibuf=CHUNK*8
    )
except Exception as e:
    print("Error initializing I2S:", e)
    i2s = None


is_play=0

def to_tts(text):
    if i2s is None:
        print("I2S not initialized.")
        return
    def audio_task():
        global is_play
        
        is_play = 1
        try:            
            # 添加超时参数（单位：秒）
            r = urequests.post(
                ASR_SERVER_URL,
                data=ujson.dumps({"text": text, "spk_id": 0}).encode('utf8'),
                headers={"Content-Type": "application/json"},  # 显式指定编码
                timeout=10  # 新增超时设置
            )            
            # 添加HTTP状态码检查
            if r.status_code != 200:
                raise Exception("Server returned: %d" % r.status_code)           
            
            # 流式处理
            while True:
                chunk = r.raw.read(CHUNK)  # 减小块大小以适应内存限制               
                if not chunk:
                    break                

                # Base64解码并转换为16位有符号整数
                pcm = ubinascii.a2b_base64(chunk)
                i2s.write(pcm)  # 直接写入I2S设备
            
            
        except OSError as e:  # 捕获底层网络错误
            print(f"tts Network Error:{e}")            
        except Exception as e:
            print("Error:", e)          
        
        is_play=0
    
    # 启动线程（MicroPython线程支持有限）
    _thread.start_new_thread(audio_task, ())

import uos
def play_wav(sfile='', sampleRate=16000, bitsPerSample=16):
    if not sfile in uos.listdir():
        print('not found ', sfile)
        return
    
    if i2s is None:
        print("I2S not initialized.")
        return   
    def wav_task():     
        f = open(sfile,'rb') 
        # 跳过文件的开头的44个字节，直到数据段的第1个字节
        pos = f.seek(44)  
        wav_samples = bytearray(1024)
        wav_samples_mv = memoryview(wav_samples) 
        while True:
            try:
                num_read = f.readinto(wav_samples_mv)            
                if num_read == 0: 
                    break 
                num_written = 0
                while num_written < num_read:
                    num_written += i2s.write(wav_samples_mv[num_written:num_read])                           
            except Exception as e:
                print("Error:", e)
            finally:
                i2s.deinit()
    _thread.start_new_thread(wav_task, ())

#to_tts("好好学习，天天向上")     

def start_out(sfile='s.wav', sampleRate=16000, bitsPerSample=16):
    if not sfile in uos.listdir():
        print('not found ', sfile)
        return
    # 初始化引脚定义
    """
    GPIO27 -- DIN
    GPIO26 --- BCLK
    GPIO2 -- LRC
    GND -- GND
    5V或3.3V -- VCC
    """
    sck_pin = Pin(26) # 串行时钟输出
    ws_pin = Pin(2)  # 字时钟
    sd_pin = Pin(27)  # 串行数据输出
     
 
    # 初始化i2s
    audio_out = I2S(1, sck=sck_pin, ws=ws_pin, sd=sd_pin,
                    mode=I2S.TX, bits=bitsPerSample, format=I2S.MONO,
                    rate=sampleRate, ibuf=20000)
 
    
    f = open(sfile,'rb')
 
    # 跳过文件的开头的44个字节，直到数据段的第1个字节
    pos = f.seek(44) 
 
    wav_samples = bytearray(1024)
    wav_samples_mv = memoryview(wav_samples)
     
    print("start out ...")
    
    #并将其写入I2S DAC
    while True:
        try:
            num_read = f.readinto(wav_samples_mv)
            
            # WAV文件结束
            if num_read == 0: 
                break
 
            # 直到所有样本都写入I2S外围设备
            num_written = 0
            while num_written < num_read:
                num_written += audio_out.write(wav_samples_mv[num_written:num_read])
                
        except Exception as ret:
            print("产生异常...", ret)
            break
    print(' out end')
